#ifndef __DCAPI_H__
#define __DCAPI_H__

#define DCAPI_VERSION	(1)

#include "dc_ioctl.h"
typedef int HDCACHANNEL;	// netlink channel
typedef int HDCAPI;			// api
typedef void* HDCAMSG;		// message
typedef void* HDCAMM;		// memory mapping

struct mem_mapping_s;

typedef struct mem_mapping_s
{
	void*					virt;		// virtual address
	unsigned long			phys;		// physical address
	unsigned long			size;		// size in bytes
	int						uncached;	// 1 - uncached, 0 - cached
	struct mem_mapping_s	*next;		// pointer to the next mapping
} mem_mapping_t;

HDCAPI dcapi_open(char* log_file_name);
void dcapi_close(HDCAPI h);
int dcapi_map(HDCAPI h, unsigned long ddr_offset, int ddr_size, int io_size);
int dcapi_unmap(HDCAPI h);
int dcapi_cm_open(HDCAPI h, unsigned int mask, int priority);
int dcapi_cm_close(HDCAPI h);
int dcapi_nl_open(HDCAPI h, unsigned int channel_mask, int priority);
int dcapi_nl_close(HDCAPI h);

int dcapi_get_addresses(HDCAPI h, void** io_base, void** cached_base, void** uncached_base);
void* dcapi_virt_to_phys(HDCAPI h, void* virt_address);
void* dcapi_phys_to_virt(HDCAPI h, void* phys_address);
int dcapi_get_sys_config(HDCAPI h, dc_mm_sys_config_t* sys_config);
int dcapi_address_is_reserved(HDCAPI h, unsigned int x);

HDCAMM dcapi_add_mem_mapping(HDCAPI h, mem_mapping_t* mapping);
int dcapi_remove_mem_mapping(HDCAPI h, HDCAMM mapping);

unsigned char dcapi_read_ioreg8(HDCAPI h, unsigned int index);
void dcapi_write_ioreg8(HDCAPI h, unsigned int index, unsigned char value);
unsigned short dcapi_read_ioreg16(HDCAPI h, unsigned int index);
void dcapi_write_ioreg16(HDCAPI h, unsigned int index, unsigned short value);
unsigned long dcapi_read_ioreg32(HDCAPI h, unsigned int index);
void dcapi_write_ioreg32(HDCAPI h, unsigned int index, unsigned long value);
void* dcapi_mmap(HDCAPI h, unsigned long phys_addr, unsigned long size, unsigned int uncached, HDCAMM* mm);
void dcapi_munmap(HDCAPI h, void* virt_addr, unsigned long size, HDCAMM mm);

int dcapi_read_memory(HDCAPI inst, unsigned long addr, void* buf, int len);
int dcapi_write_memory(HDCAPI inst, unsigned long addr, void* buf, int len);

HDCACHANNEL dcapi_open_channel(HDCAPI h, int server, unsigned int group);
int dcapi_close_channel(HDCAPI h, HDCACHANNEL channel);

HDCAMSG dcapi_allocate_message(HDCAPI h, HDCACHANNEL channel, void* buffer, int len);
void dcapi_free_message(HDCAPI h, HDCACHANNEL channel, HDCAMSG msg);
int dcapi_send_message(HDCAPI h, HDCACHANNEL channel, HDCAMSG msg);
int dcapi_receive_message(HDCAPI h, HDCACHANNEL channel, HDCAMSG msg);
int dcapi_receive_message_async(HDCAPI h, HDCACHANNEL channel, HDCAMSG msg);
void* dcapi_message_payload(HDCAMSG msg);
int dcapi_message_len(HDCAMSG msg);

int dcapi_thread_register(void* cb) __attribute__ ((deprecated));
int dcapi_thread_unregister(void* cb) __attribute__ ((deprecated));

int dc_int_register ( unsigned int id,void ( *fun ) ( void ),int priority );
int dc_int_irq_enable(unsigned int id);
int dc_int_disable(unsigned int id);

#include "linux_config.h"

#define IO_MEMORY_BASE_PHYS			0xf0000000
#define IO_MEMORY_SIZE				0x100000

#define CACHED_MEMORY_BASE_PHYS		(CONFIG_SYS_KERNEL_SDRAM_SIZE)
#define CACHED_MEMORY_SIZE			(CONFIG_SYS_SDRAM_SIZE-CONFIG_SYS_KERNEL_SDRAM_SIZE)
#define UNCACHED_MEMORY_BASE_PHYS	(0x40000000+CACHED_MEMORY_BASE_PHYS)
#define UNCACHED_MEMORY_SIZE		(CACHED_MEMORY_SIZE)

#include <stdio.h>
extern FILE* f_log_file;
#define DCAPI_LOG(...)	{ if (f_log_file) fprintf(f_log_file, __VA_ARGS__); else fprintf(stdout, __VA_ARGS__);}
#define DCAPI_ERRLOG(...) fprintf(stderr, __VA_ARGS__)

#define S_OK		(0UL)
#define MEM_PageSize dc_dmb_size_get

#define ENABLE_PAGEFAULT_PREVENTION (0)

#if ENABLE_PAGEFAULT_PREVENTION
void configure_malloc_behavior(int enable);
void reserve_process_memory(int size);
#else
#define configure_malloc_behavior(...);
#define reserve_process_memory(...);
#endif

#define ENABLE_PAGEFAULT_TRACING	(0)

#if ENABLE_PAGEFAULT_TRACING
void show_new_pagefault_count(const char* logtext, int force);
#else
#define show_new_pagefault_count(...);
#endif

#define ENABLE_APP_TRACING (1)

enum {
	APP_MESS_STARTED	= 100,
	APP_MESS_ENDED		= 101,
	APP_MESS_BLOCKED	= 102,
	APP_MESS_UNBLOCKED	= 103,
	APP_MESS_DECODER_PROGRESS = 104,
	APP_MESS_CONTAINER_BLOCKED = 105,
	APP_MESS_CONTAINER_UNBLOCKED = 106,
	APP_MESS_CONTAINER_PROGRESS = 107,
	APP_MESS_IP_PROGRESS = 108,
};

#if ENABLE_APP_TRACING
void dc_ts_init(char* filename);
void dc_ts_close(void);
void dc_ts_record(unsigned char code, unsigned char param1, unsigned char param2, unsigned char param3);
unsigned long dc_ts_read_timer(void);
#else
#define dc_ts_init(...)
#define dc_ts_close(...)
#define dc_ts_record(...)
#define dc_ts_read_timer() 0
#endif

#endif
